﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PowerMonitor.BaseCtrl;
using PowerMonitor.Common;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using System.Collections;
using PowerMonitor.Properties;

namespace PowerMonitor.ModbusDev
{
    //public struct sPolling
    //{
    //    public byte FunCode;
    //    public ushort RegAddr;
    //    public ushort RegNum;
    //    public int startIndex;
    //}
    public class InnerModbusPro
    {
        public  int strProID { get { return 0; } }                        // 协议ID
        public  string strProcName { get { return "内部Modbus协议"; } }   // 协议名称
        //private List<sPolling> SndFrame = new List<sPolling>();           // 正常轮询结构
        private List<ModbusInfo> m_SndFrame = new List<ModbusInfo>();       // 正常轮询结构
        //ModbusInfo MBInfomation = new ModbusInfo(); // 临时变量  避免重复创建
        private int m_iSendIndex = 0;
        public byte[] m_bDataToSend = null;
        public  string strVesion { get { return "V14-10-0-001"; } }           // 协议版本
        /// <summary>
        /// 初始化轮询结构  （）
        /// </summary>
        /// <param name="pDevice"></param>
        /// <returns></returns>
        public bool InitSendFrame(ref InnerModbusDevice pDevice)
        {
            m_iSendIndex = 0;
            return GetSendInfo(ref pDevice);
        }
        /// <summary>
        /// 根据表内容获取发送报文信息 功能码 寄存器起始地址 个数 
        /// </summary>
        /// <param name="pDevice">装置信息</param>
        /// <returns></returns>
        private bool GetSendInfo(ref InnerModbusDevice pDevice)
        {
            if (pDevice.GetDataList() == null || pDevice.GetDataItemCnt() == 0)
            {
                return false;
            }
            m_SndFrame.Clear();  // 清空列表
            ModbusInfo MbPoll;
            byte byFun = 0x03;
            ushort startAddr = 0, CurrAddr = 0xEFFF;
            ushort RegCount = 0,stepCnt = 2, LastStep = 0;
            int offset = -1;  // 记录起始行号
            eDataType DataType; // 数据类型
            bool bFirstRead = true; // 标志是否为 连续读取数据项的 第一个数据项
            for (int i = 0; i < pDevice.GetDataItemCnt(); i++)
            {
                //if (pDevice.GetDataItem(i).IsSummation)
                //{
                    DataType = pDevice.GetDataItem(i).dataType; // 数据类型
                    if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT || DataType == eDataType.BCD8 || DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4)
                    {
                        stepCnt = 2; // 两个寄存器 
                    }
                    else if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3 || DataType == eDataType.WORD || DataType == eDataType.BYTE)
                    {
                        stepCnt = 1; // 一个寄存器
                    }
                    else if (DataType == eDataType.DOUBLE || DataType == eDataType.LONG)
                    {
                        stepCnt = 4;
                    }

                    if (bFirstRead)
                    {
                        bFirstRead = false;  // 
                        byFun = pDevice.GetDataItem(i).bFunCode;       // 功能码
                        startAddr = pDevice.GetDataItem(i).usRegAddr;  // 寄存器地址
                        CurrAddr = startAddr;
                        LastStep = stepCnt;
                        offset = i; // 记录起始行号
                    }
                    else
                    {
                        CurrAddr += LastStep;
                        if (CurrAddr == pDevice.GetDataItem(i).usRegAddr && byFun == pDevice.GetDataItem(i).bFunCode)
                        {
                            RegCount += LastStep;
                            LastStep = stepCnt;
                            CurrAddr = pDevice.GetDataItem(i).usRegAddr;
                        }
                        else
                        {
                            MbPoll = new ModbusInfo();
                            MbPoll.FunCode = byFun;
                            MbPoll.RegAddr = startAddr;

                            MbPoll.RegNum = (ushort)(RegCount + LastStep);
                            LastStep = stepCnt;

                            MbPoll.startIndex = offset; // 标记起始记录行号
                            m_SndFrame.Add(MbPoll);
                            startAddr = pDevice.GetDataItem(i).usRegAddr;  // 寄存器地址
                            byFun = pDevice.GetDataItem(i).bFunCode;       // 功能码
                            RegCount = 0;
                            offset = i;
                            CurrAddr = startAddr;
                        }
                    }
                //}
                //else
                //{
                //    if (offset >= 0)
                //    {
                //        MbPoll = new ModbusInfo();
                //        MbPoll.FunCode = byFun;
                //        MbPoll.RegAddr = startAddr;
                //        MbPoll.RegNum = (ushort)(RegCount + LastStep);
                //        LastStep = stepCnt;
                //        RegCount = 0;
                //        MbPoll.startIndex = offset; // 标记起始记录行号
                //        m_SndFrame.Add(MbPoll);
                //    }
                //    bFirstRead = true;
                //    offset = -1;
                //    continue;
                //}
            }
            if (offset < 0 )
            {
                if (m_SndFrame.Count <= 0)
                {
                    return false;
                }
                else if (m_SndFrame.Count > 0)
                {
                    return true;
                }
            }
           
            MbPoll = new ModbusInfo();
            MbPoll.FunCode = pDevice.GetDataItem(offset).bFunCode;
            MbPoll.RegAddr = startAddr;
            MbPoll.RegNum = (ushort)(RegCount + stepCnt);
            MbPoll.startIndex = offset;// 标记起始记录行号
            m_SndFrame.Add(MbPoll);
            if (m_SndFrame.Count <= 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        /// <summary>
        /// 根据表内容获取发送报文信息 功能码 寄存器起始地址 个数 
        /// </summary>
        /// <param name="pDevice">装置信息</param>
        /// <returns></returns>
        private bool GetSendInfo0(ref InnerModbusDevice pDevice)
        {
            if (pDevice.GetDataList() == null || pDevice.GetDataItemCnt() == 0)
            {
                return false;
            }
            m_SndFrame.Clear();  // 清空列表
            ModbusInfo MbPoll;
            byte byFun = 0x03;
            ushort startAddr = 0, CurrAddr = 0xEFFF;
            ushort RegCount = 0;
            ushort stepCnt = 2,LastStep = 0;
            int offset = 0;
            eDataType DataType; // 数据类型
            byFun = pDevice.GetDataItem(0).bFunCode;       // 功能码
            startAddr = pDevice.GetDataItem(0).usRegAddr;  // 寄存器地址
            CurrAddr = startAddr;
            DataType = pDevice.GetDataItem(0).dataType; // 数据类型
            if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT || DataType == eDataType.BCD8 || DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4)
            {
                stepCnt = 2; // 两个寄存器 
            }
            else if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3 || DataType == eDataType.WORD || DataType == eDataType.BYTE)
            {
                stepCnt = 1; // 一个寄存器
            }
            else if (DataType == eDataType.DOUBLE || DataType == eDataType.LONG)
            {
                stepCnt = 4;
            }
            LastStep = stepCnt;
            for (int i = 1; i < pDevice.GetDataItemCnt(); i++)
            {
                DataType = pDevice.GetDataItem(i).dataType; // 数据类型

                if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT || DataType == eDataType.BCD8 || DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4)
                {
                    stepCnt = 2; // 两个寄存器 
                }
                else if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3 || DataType == eDataType.WORD || DataType == eDataType.BYTE)
                {
                    stepCnt = 1; // 一个寄存器
                }
                else if (DataType == eDataType.DOUBLE || DataType == eDataType.LONG)
                {
                    stepCnt = 4;
                }
                CurrAddr += LastStep;
                if (CurrAddr == pDevice.GetDataItem(i).usRegAddr && byFun == pDevice.GetDataItem(i).bFunCode)
                {
                    RegCount += LastStep;
                    LastStep = stepCnt;
                    CurrAddr = pDevice.GetDataItem(i).usRegAddr;
                }
                else
                {
                    MbPoll = new ModbusInfo();
                    MbPoll.FunCode = byFun;
                    MbPoll.RegAddr = startAddr;

                    MbPoll.RegNum = (ushort)(RegCount + LastStep);
                    LastStep = stepCnt;

                    MbPoll.startIndex = offset; // 标记起始记录行号
                    m_SndFrame.Add(MbPoll);
                    startAddr = pDevice.GetDataItem(i).usRegAddr;  // 寄存器地址
                    byFun = pDevice.GetDataItem(i).bFunCode;       // 功能码
                    RegCount = 0;
                    offset = i;
                    CurrAddr = startAddr;
                }
            }
            MbPoll = new ModbusInfo();
            MbPoll.FunCode = pDevice.GetDataItem(offset).bFunCode;
            MbPoll.RegAddr = startAddr;
            MbPoll.RegNum = (ushort)(RegCount + stepCnt);
            MbPoll.startIndex = offset;// 标记起始记录行号
            m_SndFrame.Add(MbPoll);
            if (m_SndFrame.Count <= 0)
            {
                return false; 
            }
            else
            {
                return true;
            }
        }
        /// <summary>
        /// 打包外部发送数据（插帧）
        /// </summary>
        /// <param name="Addr">装置地址</param>
        /// <param name="List_Data">数据项容器</param>
        /// <param name="bytesqueue">字节顺序</param>
        /// <returns></returns>
        public List<ModbusInfo> GetSendFrame(byte Addr, List<DevDataItem> List_Data,eByteSqueue bytesqueue)
        {
            List<ModbusInfo> List_Polling = new List<ModbusInfo>();
            if (List_Data == null || List_Data.Count == 0)
            {
                return List_Polling;
            }
            List_Polling.Clear();  // 清空列表
            ModbusInfo poll;
            byte byFun = 0x03;
            ushort startAddr = 0, CurrAddr = 0xEFFF;
            ushort RegCount = 0;
            ushort stepCnt = 2, LastStep = 0;
            int offset = 0;
            eDataType DataType; // 数据类型
            byFun = List_Data[0].bFunCode;       // 功能码
            startAddr = List_Data[0].usRegAddr;  // 寄存器地址
            CurrAddr = startAddr;
            DataType = List_Data[0].dataType; // 数据类型
            if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT || DataType == eDataType.BCD8 || DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4)
            {
                stepCnt = 2; // 两个寄存器 
            }
            else if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3 || DataType == eDataType.WORD || DataType == eDataType.BYTE)
            {
                stepCnt = 1; // 一个寄存器
            }
            else if (DataType == eDataType.DOUBLE || DataType == eDataType.LONG)
            {
                stepCnt = 4;
            }
            LastStep = stepCnt;
            for (int i = 1; i < List_Data.Count; i++)
            {
                DataType = List_Data[i].dataType; // 数据类型

                if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT || DataType == eDataType.BCD8 || DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4)
                {
                    stepCnt = 2; // 两个寄存器 
                }
                else if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3 || DataType == eDataType.WORD || DataType == eDataType.BYTE)
                {
                    stepCnt = 1; // 一个寄存器
                }
                else if (DataType == eDataType.DOUBLE || DataType == eDataType.LONG)
                {
                    stepCnt = 4;
                }
                CurrAddr += LastStep;

                if (CurrAddr == List_Data[i].usRegAddr && byFun == List_Data[i].bFunCode)
                {
                    RegCount += LastStep;
                    LastStep = stepCnt;
                    CurrAddr = List_Data[i].usRegAddr;
                }
                else
                {
                    poll = new ModbusInfo();
                    poll.FunCode = byFun;
                    poll.RegAddr = startAddr;
                    poll.RegNum = (ushort)(RegCount + LastStep);
                    LastStep = stepCnt;

                    poll.startIndex = List_Data[offset].ItemId; // 标记起始记录行号
                    List_Polling.Add(poll);
                    startAddr = List_Data[i].usRegAddr;  // 寄存器地址
                    byFun = List_Data[i].bFunCode;       // 功能码
                    RegCount = 0;
                    offset = i;
                    CurrAddr = startAddr;
                }
            }
            poll = new ModbusInfo();
            poll.FunCode = List_Data[offset].bFunCode;
            poll.RegAddr = startAddr;
            poll.RegNum = (ushort)(RegCount + stepCnt);
            poll.startIndex = List_Data[offset].ItemId;// 标记起始记录行号
            List_Polling.Add(poll);
            if (List_Polling.Count <= 0)
            {
                return List_Polling;
            }
            else
            {
                ArrayList bytes = new ArrayList();
                for (int i = 0; i < List_Polling.Count; i++)
                {
                    List_Polling[i].DevAddr = Addr;
                    
                    if (List_Polling[i].FunCode != 0x03)
                    {
                        int cnt = 0;
                        if (i < List_Polling.Count - 1)
                        {
                            bytes.Clear();
                            for (int j = List_Polling[i].startIndex; j <= List_Polling[i + 1].startIndex; j++)
                            {
                                if (List_Polling[i].FunCode != List_Polling[i + 1].FunCode)
                                {
                                    for (int k = 0; k < List_Data.Count;k++ )
                                    {
                                        if (List_Data[k].ItemId == List_Polling[i].startIndex + cnt && List_Data[k].bFunCode == List_Polling[i].FunCode)
                                        {
                                            cnt++;
                                            bytes.AddRange(GetBytesFromData(List_Data[k].dWriteValue, List_Data[k].dmult, List_Data[k].dataType, bytesqueue));
                                        }
                                        else
                                        {
                                            if (cnt!=0)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    break;
                                }
                                else
                                {
                                    for (int k = 0; k < List_Data.Count; k++)
                                    {
                                        if (List_Data[k].ItemId == List_Polling[i].startIndex + cnt && List_Data[k].ItemId != List_Polling[i+1].startIndex && List_Data[k].bFunCode == List_Polling[i].FunCode)
                                        {
                                            cnt++;
                                            bytes.AddRange(GetBytesFromData(List_Data[k].dWriteValue, List_Data[k].dmult, List_Data[k].dataType, bytesqueue));
                                        }
                                        else
                                        {
                                            if (cnt != 0)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }

                            }
                        }
                        else
                        {
                            for (int k = 0; k < List_Data.Count; k++)
                            {
                                if (List_Data[k].ItemId == List_Polling[i].startIndex + cnt && List_Data[k].bFunCode == List_Polling[i].FunCode)
                                {
                                    cnt++;
                                    bytes.AddRange(GetBytesFromData(List_Data[k].dWriteValue, List_Data[k].dmult, List_Data[k].dataType, bytesqueue));
                                }
                                else
                                {
                                    if (cnt != 0)
                                    {
                                        break;
                                    }
                                }
                            } 
                        }
                    }

                    if (bytes.Count>0)
                    {
                        List_Polling[i].WriteData = (byte[])bytes.ToArray(typeof(byte));
                        bytes.Clear();
                    }
                    ModbusInfo mod = List_Polling[i];
                    if (!Modbus.MakeSendFrame(ref mod))
                    {
                        continue;
                    }
                }
                return List_Polling;
            }
        }
        /// <summary>
        /// 获取不同字节顺序，数据类型的转换字节
        /// </summary>
        /// <param name="dData"></param>
        /// <param name="dmult"></param>
        /// <param name="dataType"></param>
        /// <param name="byteSqueue"></param>
        /// <returns></returns>
        public byte[] GetBytesFromData(double dData, double dmult,eDataType dataType, eByteSqueue byteSqueue)
        {
            byte[] byData = null;
            try
            {
                switch (dataType)
                {
                    case eDataType.SHORT:
                        byData = BitConverter.GetBytes(Convert.ToInt16((dData / dmult)));
                        break;
                    case eDataType.INT32:
                        byData = BitConverter.GetBytes(Convert.ToInt32((dData / dmult)));
                        break;
                    case eDataType.FLOAT:
                        byData = BitConverter.GetBytes(Convert.ToSingle((dData / dmult)));
                        break;
                    case eDataType.USHORT:
                        byData = BitConverter.GetBytes(Convert.ToUInt16((dData / dmult)));
                        break;
                    case eDataType.UINT32:
                        byData = BitConverter.GetBytes(Convert.ToUInt32((dData / dmult)));
                        break;
                    case eDataType.LONG:
                        byData = BitConverter.GetBytes(Convert.ToInt64((dData / dmult)));
                        break;
                    case eDataType.DOUBLE:
                        byData = BitConverter.GetBytes(dData / dmult);
                        break;
                    case eDataType.BYTE:
                        byData = BitConverter.GetBytes(Convert.ToByte((dData / dmult)));
                        break;
                    case eDataType.BCD8:
                        byData = BitConverter.GetBytes(Convert.ToUInt32((dData / dmult).ToString(), 16));
                        break;
                    case eDataType.BCD6_2:
                        byData = BitConverter.GetBytes(Convert.ToUInt32((dData * 100 / dmult).ToString(), 16));
                        break;
                    case eDataType.BCD4_4:
                        byData = BitConverter.GetBytes(Convert.ToUInt32((dData * 10000 / dmult).ToString(), 16));
                        break;
                    case eDataType.BCD4:
                        byData = BitConverter.GetBytes(Convert.ToUInt16((dData / dmult).ToString(), 16));
                        break;
                    case eDataType.BCD2_2:
                        byData = BitConverter.GetBytes(Convert.ToUInt16((dData * 100 / dmult).ToString(), 16));
                        break;
                    case eDataType.BCD1_3:
                        byData = BitConverter.GetBytes(Convert.ToUInt16((dData * 1000 / dmult).ToString(), 16));
                        break;
                    default:
                        return null;
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message, "数据转换错误");
                return null;
            }
            if (byData == null)
            {
                return null;
            }
            switch (byteSqueue)
            {
                case eByteSqueue.高位在前:         // 高位在前4321
                case eByteSqueue.高字在前:         // 高字在前4321
                    Array.Reverse(byData, 0, byData.Length);
                    break;
                case eByteSqueue.低位在前:         // 低位在前1234
                    break;
                case eByteSqueue.低字在前:         // 低字在前2143
                    for (int i = 0; i < byData.Length / 2; i++)
                    {
                        Array.Reverse(byData, 2 * i, 2);
                    }
                    break;
                case eByteSqueue.三四一二:         // 3412
                    if (byData.Length > 2)
                    {
                        for (int i = 0; i < byData.Length / 2; i++)
                        {
                            Array.Reverse(byData, 2 * i, 2);
                        }
                        for (int i = 0; i < byData.Length / 4; i++)
                        {
                            Array.Reverse(byData, 4 * i, 4);
                        }
                    }
                    break;
                default:
                    for (int i = 0; i < byData.Length / 4; i++)
                    {
                        byData[i] = 0;
                    }
                    break;
            }
            return byData;
        }
        /// <summary>
        /// 发送数据打包
        /// </summary>
        /// <param name="pDevice"></param>
        /// <returns></returns>
        public bool MakeSendData(ref InnerModbusDevice pDevice)    // 打包待发送数据
        {
            if (m_SndFrame.Count == 0)
            {
                return false;
            }
            else
            {
                m_SndFrame[m_iSendIndex].DevAddr = pDevice.bAddr;
                ModbusInfo modinfo = m_SndFrame[m_iSendIndex];
                if (Modbus.MakeSendFrame(ref modinfo) == false)
                {
                    m_iSendIndex++;
                    if (m_iSendIndex >= m_SndFrame.Count)
                    {
                        m_iSendIndex = 0;
                    }
                    return false;
                }

                m_bDataToSend = modinfo.SendADU;
                m_iSendIndex++;
                if (m_iSendIndex >= m_SndFrame.Count)
                {
                    m_iSendIndex = 0;
                }
            }
            return true;
        }
        /// <summary>
        /// 处理接收数据（原始报文）
        /// </summary>
        /// <param name="pData">接收报文</param>
        /// <param name="pDevice">当前收发装置</param>
        /// <param name="modinfo">报文附加信息（插帧时使用）</param>
        /// <returns></returns>
        public bool DealReceiveData(byte[] pData,ref InnerModbusDevice pDevice,ModbusInfo modinfo)  // 检查接收包 
        {
            ModbusInfo Info = null;
            if (modinfo != null)
            {
                modinfo.RecADU = pData;
                Info = modinfo;
            }
            else
            {
                if (m_iSendIndex != 0)
                {
                    Info = m_SndFrame[m_iSendIndex - 1];
                }
                else
                {
                    Info = m_SndFrame[m_SndFrame.Count - 1];
                }
                Info.RecADU = pData;
            }
           
            if (Modbus.MB_NO_ERROR != Modbus.CheckRecFrame(ref Info))
            {
                return false;
            }
            else
            {
                if (Info.FunCode != 0x03)
                {
                    return true;
                }
                byte[] DataSrc = new byte[pData.Length - 5];
                Buffer.BlockCopy(pData, 3, DataSrc, 0, pData.Length - 5);

                if (ExplainReceiveData(ref pDevice, DataSrc, Info))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            
            }
        }

        /// <summary>
        /// 解析接收报文
        /// </summary>
        /// <param name="RecData"></param>
        /// <returns></returns>
        private bool ExplainReceiveData(ref InnerModbusDevice pDevice,byte[] DataSrc,ModbusInfo CurPoll)
        {
            bool bRes = true;
            try
            {
                int offset = 0, index = CurPoll.startIndex;//index = pollInfo[RxTxCtrl.readIndex].startIndex
                double dMult = 0;
                eDataType DataType = eDataType.INT32;
                DevDataItem temp;
                switch (pDevice.byteSqueue)
                {
                    case eByteSqueue.高位在前:         // 高位在前4321
                    case eByteSqueue.高字在前:         // 高位在前4321
                        while (offset < DataSrc.Length && index < pDevice.GetDataItemCnt())
                        {
                            DataType = pDevice.GetDataItem(index).dataType;
                            double dl = pDevice.GetDataItem(index).dCurValue;
                            dMult = pDevice.GetDataItem(index).dmult;
                            temp = pDevice.GetDataItem(index);
                            if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.WORD)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                Array.Reverse(DataSrc, offset, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                Array.Reverse(DataSrc, offset, 4);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else if (DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3)  // 4位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4 || DataType == eDataType.BCD8) // 八位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else //if (DataType == eDataType.DOUBLE || DataType == eDataType.LONG || DataType == eDataType.BYTE) // ??? 未实现
                            {
                            }
                            index++;
                        }
                        break;
                    case eByteSqueue.低位在前:    // 低位在前1234
                        while (offset < DataSrc.Length && index < pDevice.GetDataItemCnt())
                        {
                            DataType = pDevice.GetDataItem(index).dataType;
                            dMult = pDevice.GetDataItem(index).dmult;
                            temp = pDevice.GetDataItem(index);
                            if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.WORD)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else if (DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3)  // 4位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                Array.Reverse(DataSrc, offset, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4 || DataType == eDataType.BCD8) // 八位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                Array.Reverse(DataSrc, offset, 4);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else
                            {
                            }
                            index++;
                        }
                        break;
                    case eByteSqueue.低字在前:         // 低字在前2143
                        while (offset < DataSrc.Length && index < pDevice.GetDataItemCnt())
                        {
                            DataType = pDevice.GetDataItem(index).dataType;
                            dMult = pDevice.GetDataItem(index).dmult;
                            temp = pDevice.GetDataItem(index);
                            if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.WORD)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                Array.Reverse(DataSrc, offset, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                for (int i = 0; i < 2; i++)
                                {
                                    Array.Reverse(DataSrc, offset + 2 * i, 2);
                                }
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else if (DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3)  // 4位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4 || DataType == eDataType.BCD8) // 八位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                for (int i = 0; i < 2; i++)
                                {
                                    Array.Reverse(DataSrc, offset + 2 * i, 2);
                                }
                                Array.Reverse(DataSrc, offset, 4);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else
                            {
                            }
                            index++;
                        }
                        break;
                    case eByteSqueue.三四一二:         // 3412
                        while (offset < DataSrc.Length && index < pDevice.GetDataItemCnt())
                        {
                            DataType = pDevice.GetDataItem(index).dataType;
                            dMult = pDevice.GetDataItem(index).dmult;
                            temp = pDevice.GetDataItem(index);
                            if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.WORD)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;

                            }
                            else if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                for (int i = 0; i < 2; i++)
                                {
                                    Array.Reverse(DataSrc, offset + 2 * i, 2);
                                }
                                Array.Reverse(DataSrc, offset, 4);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else if (DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3)  // 4位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                Array.Reverse(DataSrc, offset, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4 || DataType == eDataType.BCD8) // 八位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                for (int i = 0; i < 2; i++)
                                {
                                    Array.Reverse(DataSrc, offset + 2 * i, 2);
                                }
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else
                            {
                            }
                            index++;
                        }
                        break;
                    default: // "4321"
                        while (offset < DataSrc.Length && index < pDevice.GetDataItemCnt())
                        {
                            DataType = pDevice.GetDataItem(index).dataType;
                            dMult = pDevice.GetDataItem(index).dmult;
                            temp = pDevice.GetDataItem(index);
                            if (DataType == eDataType.SHORT || DataType == eDataType.USHORT || DataType == eDataType.WORD)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                Array.Reverse(DataSrc, offset, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.INT32 || DataType == eDataType.UINT32 || DataType == eDataType.FLOAT)
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                Array.Reverse(DataSrc, offset, 4);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else if (DataType == eDataType.BCD4 || DataType == eDataType.BCD2_2 || DataType == eDataType.BCD1_3)  // 4位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 2);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 2;
                            }
                            else if (DataType == eDataType.BCD6_2 || DataType == eDataType.BCD4_4 || DataType == eDataType.BCD8) // 八位BCD码
                            {
                                Buffer.BlockCopy(DataSrc, offset, temp.RawBytes, 0, 4);
                                temp.dCurValue = Math.Round(ExplainData(DataType, DataSrc, offset, dMult, temp.PointNum), temp.PointNum);
                                offset += 4;
                            }
                            else
                            {
                            }
                            index++;
                        }
                        break;
                }
                return bRes;
            }
            catch
            {
                return bRes;
            }
        }
        /// <summary>
        /// 解析接收报文为实际值
        /// </summary>
        /// <param name="DataType">数据类型</param>
        /// <param name="DataSrc">报文字节</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="Multiple">放大倍数</param>
        /// <returns></returns>
        private double ExplainData(eDataType DataType, byte[] DataSrc, int startIndex, double Multiple,int PointNum)
        {
            double tempVal = 0;
            if (Multiple < 1)
            {
                Multiple = Math.Round(Multiple, PointNum);  // 由于Multiple为浮点型，不能准确表示数值，
            }                                               // 当被乘数较大时，会产生不少误差，故要四舍五入 
            switch (DataType)
            {
                case eDataType.SHORT: // 短整形
                    try
                    {
                        tempVal = (BitConverter.ToInt16(DataSrc, startIndex) + 0.000001) * Multiple;
                    }
                    catch
                    { }
                    break;
                case eDataType.INT32: // 整形
                    try
                    {
                        tempVal = (BitConverter.ToInt32(DataSrc, startIndex) + 0.000001) * Multiple;
                    }
                    catch
                    { }
                    break;
                case eDataType.USHORT: // 短整形
                case eDataType.WORD: // 
                    try
                    {
                        tempVal = (BitConverter.ToUInt16(DataSrc, startIndex) + 0.000001) * Multiple;
                    }
                    catch
                    { }
                    break;
                case eDataType.UINT32: // 整形
                    try
                    {
                        tempVal = (BitConverter.ToUInt32(DataSrc, startIndex) + 0.000001) * Multiple;
                    }
                    catch
                    { }
                    break;
                case eDataType.FLOAT: // 浮点型
                    try
                    {
                        tempVal = BitConverter.ToSingle(DataSrc, startIndex) * Multiple + 0.000001;
                    }
                    catch
                    { }
                    break;
                case eDataType.DOUBLE:
                    try
                    {
                        tempVal = BitConverter.ToDouble(DataSrc, startIndex) * Multiple + 0.000001;
                    }
                    catch
                    { }
                    break;
                case eDataType.BCD8:
                case eDataType.BCD6_2:
                case eDataType.BCD4_4:
                    try
                    {
                        StringBuilder strB = new StringBuilder();
                        for (int i = startIndex; i < startIndex + 4; i++)
                        {
                            strB.Append(DataSrc[i].ToString("X2"));
                        }
                        int TempVal = int.Parse(strB.ToString());
                        if (eDataType.BCD6_2 == DataType)
                        {
                            tempVal = TempVal * 0.01 * Multiple + 0.000001;
                        }
                        else if (eDataType.BCD4_4 == DataType)
                        {
                            tempVal = TempVal * 0.0001 * Multiple + 0.000001;
                        }
                        else if (eDataType.BCD8 == DataType)
                        {
                            tempVal = TempVal * Multiple;
                        }
                    }
                    catch
                    { }
                    break;
                case eDataType.BCD4:
                case eDataType.BCD2_2:
                case eDataType.BCD1_3:
                    try
                    {
                        StringBuilder strB = new StringBuilder();
                        for (int i = startIndex; i < startIndex + 2; i++)
                        {
                            strB.Append(DataSrc[i].ToString("X2"));
                        }
                        int TempVal = int.Parse(strB.ToString());
                        if (eDataType.BCD2_2 == DataType)
                        {
                            tempVal = TempVal * 0.01 * Multiple + 0.000001;
                        }
                        else if (eDataType.BCD1_3 == DataType)
                        {
                            tempVal = TempVal * 0.001 * Multiple + 0.000001;
                        }
                        else if (eDataType.BCD4 == DataType)
                        {
                            tempVal = TempVal * Multiple;
                        }
                    }
                    catch
                    { }
                    break;
                default:   
                    try
                    {
                        tempVal = (BitConverter.ToUInt16(DataSrc, startIndex) + 0.000001) * Multiple;
                    }
                    catch
                    { }
                    break;
            }
            return tempVal;//.ToString(strFormat)
               
        }
    }
   
    /// <summary>
    /// 内置通用版Modbus 装置
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public class InnerModbusDevice : BaseDevice
    {
        public InnerModbusPro m_Protocol;           // 关联协议    初始化设备数据后  必须调用InitSendFrame
        public InnerModbusDevice()
        {
            bAddr = 1;
            //isConnected = false;
            isWorking = true;
            NotRecieveCnt = BreakOffCnt + 1;
            DeviceId = 1;
            MaxSendCnt = 2;
            Name = Resources.txtNewDevice;
            m_FreshTime = DateTime.Now;
            byteSqueue = eByteSqueue.高位在前;
            m_DataList = new List<DevDataItem>();
            m_Protocol = new InnerModbusPro(); // 初始化设备数据后  必须调用InitSendFrame
        }
        public InnerModbusDevice(string strName, InnerModbusChannel chl)
        {
            bAddr = 1;
            //isConnected = false;
            isWorking = true;
            NotRecieveCnt = BreakOffCnt+1;
            ChannelId = chl.baseChlPara.ChannelId;
            DeviceId = 0;
            if (chl.m_DeviceList.Count > 0)
            {
                DeviceId = chl.m_DeviceList[chl.m_DeviceList.Count - 1].DeviceId + 1;
            }
            MaxSendCnt = 2;
            Name = strName;
            m_FreshTime = DateTime.Now;
            byteSqueue = eByteSqueue.高位在前;
            m_DataList = new List<DevDataItem>();
            m_Protocol = new InnerModbusPro(); // 初始化设备数据后  必须调用InitSendFrame
        }
        ~InnerModbusDevice()
        {
            
        }
        public void DeviceCopyFrom(InnerModbusDevice ModDevice)
        {
            bAddr = (byte)(ModDevice.bAddr+1);
            DeviceId = ModDevice.DeviceId + 1;
            Name = ModDevice.Name;
            byteSqueue = ModDevice.byteSqueue;
            m_DataList = ModDevice.m_DataList;
        }
    }

    public class InnerModbusChannel : Channel
    {
        private ComPara _ChlPara;
        private BackgroundWorker ChannelThread = new BackgroundWorker();     // 轮询线程
        public int ReSendCnt = 1;                   // 发送次数 初始值为1(无接收时开始计数 与装置允许重发次数比较)
        private int m_iCurSend = 0;                   // 当前发送数据的装置
        public List<InnerModbusDevice> m_DeviceList = new List<InnerModbusDevice>();    // 装置列表
        private List<ModbusInfo> InsertList = new List<ModbusInfo>();                   // 插帧 正常收发时 自动移除
        public InnerModbusDevice m_CurDevice = null;
        public InnerModbusDevice tempDev = null;
        public ComPara ComChlPara
        {
            get { return _ChlPara as ComPara; }
            set
            {
                if (value is ComPara)
                {
                    _ChlPara = value as ComPara;
                }
                else
                {
                    Exception ex = new Exception("通道参数错误！");
                    throw ex;
                }
            }
        }
        /// <summary>
        /// 须初始化ComPara通道参数
        /// </summary>
        public InnerModbusChannel()
        {
            _ChlPara = new ComPara(0, Resources.txtNewChannel);
            baseChlPara = _ChlPara;
            m_CurDevice = new InnerModbusDevice("未初始化", this);
            // m_BaseDevList = m_DeviceList as List<Devices>;
        }
        public InnerModbusChannel(ComPara Para)
        {
            baseChlPara = Para;
            _ChlPara = Para;
            m_CurDevice = new InnerModbusDevice("未初始化", this);
        }

        /// <summary>
        /// 获取通道下挂载的设备总数 
        /// </summary>
        /// <returns></returns>
        public override int GetDevicesCnt()
        {
            return m_DeviceList.Count;
        }
        /// <summary>
        /// 获取index处的设备 没有这返回null
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public override BaseDevice GetDevByIndex(int index)
        {
            if (index >= m_DeviceList.Count)
            {
                return null;
            }
            return m_DeviceList[index];
        }
        /// <summary>
        /// 插帧数据打包
        /// </summary>
        /// <param name="InsertContent"></param>
        /// <returns></returns>
        public override bool InsertFrame(object InsertContent) // 应移动至协议层实现
        {
            if (InsertContent is ModbusInfo)
            {
                ModbusInfo modInfo = InsertContent as ModbusInfo;
                if (Modbus.MakeSendFrame(ref modInfo) == true)
                {
                    InsertList.Add(modInfo);
                    return true;
                }
            }
            return false;
        }
        public override bool InsertFrame(int devId,List<DevDataItem> DataList)
        {
            if (DataList == null || DataList.Count == 0 || devId < 0 || devId > m_DeviceList.Count)
            {
                return false;
            }
            else
            {
                List<ModbusInfo> tempMod = m_DeviceList[devId].m_Protocol.GetSendFrame(m_DeviceList[devId].bAddr, DataList, m_DeviceList[devId].byteSqueue);
                if (tempMod == null || tempMod.Count == 0)
                {
                    return false;
                }
                else
                {
                    for (int i = 0; i < tempMod.Count;i++ )
                    {
                        if (tempMod[i].SendADU == null)
                        {
                            tempMod.RemoveAt(i);
                        }
                        tempMod[i].DevId = devId;
                    }
                    if (tempMod.Count > 0)
                    {
                        InsertList.AddRange(tempMod);
                    }
                    else
                    {
                        return false;
                    }
                    return true;
                }
            }
        }
        public override int GetInsertFrameCnt()
        {
            return InsertList.Count;
        }
        /// <summary>
        /// 开始轮询
        /// </summary>
        /// <returns></returns>
        public override bool StartPolling()
        {
            if (m_DeviceList.Count==0)
            {
                return false;
            }
            else
            {
                m_iCurSend = 0;
                m_CurDevice = m_DeviceList[m_iCurSend];
            }
            if (ChannelThread == null)
            {
                ChannelThread = new BackgroundWorker();
            }
            if (ChannelThread.IsBusy)
            {
                return false;
            }
            if (!ComChlPara.ComPort.IsOpen)
            {
                try
                {
                    ComChlPara.ComPort.Open();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return false;
                }
            }
            InnerModbusDevice dev;
            for (int i = 0;i < m_DeviceList.Count;i++)
            {
                dev =  m_DeviceList[i];
                dev.m_Protocol.InitSendFrame(ref dev);
            }
            
            ChannelThread.WorkerSupportsCancellation = true;
            ChannelThread.DoWork += RunPollingThread;
            ChannelThread.RunWorkerCompleted += RunWorkerCompleted;
            ChannelThread.RunWorkerAsync();
            return true;
        }
        /// <summary>
        /// 停止轮询
        /// </summary>
        public override void StopPolling()
        {
            if (ChannelThread == null)
            {
                return;
            }
            if (ChannelThread.IsBusy)
            {
                ChannelThread.CancelAsync();
            }
            if (ComChlPara.ComPort.IsOpen)
            {
               ComChlPara.ComPort.Close();
            }
        }
        /// <summary>
        /// 获取通道状态（true运行 false 停止）
        /// </summary>
        /// <returns></returns>
        public override bool GetChannelState()
        {
            if (ChannelThread != null&&ChannelThread.IsBusy)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private string GetStrFromBytes(byte[] bys)
        {
            StringBuilder strB = new StringBuilder();
            foreach (byte b in bys)
            {
                strB.Append(b.ToString("X2") + " ");
            }
            return strB.ToString();
        }
        private void RunPollingThread(Object sender, DoWorkEventArgs e)
        {
            System.Object lockThis = new System.Object();
            msgInfo msg = new msgInfo();
            //int isleepTime = PollingTime - ComChlPara.iTimeOut;
            int DevIndex = 0;// 用于搜寻可用设备
            bool bCheckRes = false;  // 接收报文检验结果
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            msg.chlId = ComChlPara.ChannelId;

            while (!ChannelThread.CancellationPending)
            {
                if (InsertList.Count > 0)   // 是否有插帧
                {
                    SendBlock(InsertList[0].SendADU); // 发送插帧
                    
                    ////////////报文显示/////////////////////////////
                    msg.msgType = eMsgType.msgInsSend;
                    msg.devId = InsertList[0].DevId;
                    msg.sendtime = DateTime.Now;
                    msg.msgBytes = InsertList[0].SendADU;
                    if (AppMain.MainForm.FrmShowMsg.IChlId == ComChlPara.ChannelId || AppMain.MainForm.FrmShowMsg.IChlId == msg.devId)
                    {
                        AppMain.msgQueue.Enqueue(msg);
                    }
                    ///////////////////////////////////////////
                }
                else
                {
                    if (m_CurDevice.m_Protocol.MakeSendData(ref m_CurDevice)) // 根据协议内部查询
                    {
                        SendBlock(m_CurDevice.m_Protocol.m_bDataToSend); // 发送轮询
                        ////////////报文显示/////////////////////////////
                        msg.msgType = eMsgType.msgSend;
                        msg.devId = m_CurDevice.DeviceId;
                        msg.sendtime = DateTime.Now;
                        msg.msgBytes = m_CurDevice.m_Protocol.m_bDataToSend;
                        if (AppMain.MainForm.FrmShowMsg.IChlId == ComChlPara.ChannelId || AppMain.MainForm.FrmShowMsg.IChlId == msg.devId)
                        {
                            AppMain.msgQueue.Enqueue(msg);
                        }
                        ///////////////////////////////////////////////////////
                    }
                    else
                    {
                        do
                        {
                            m_iCurSend++;                             // 可以考虑锁定发送一台装置的数据
                            if (m_iCurSend >= m_DeviceList.Count)
                            {
                                m_iCurSend = 0;
                            }
                        } while (!m_DeviceList[m_iCurSend].isWorking && (++DevIndex) < m_DeviceList.Count);
                        if (DevIndex < m_DeviceList.Count || m_DeviceList[m_iCurSend].isWorking)
                        {
                            m_CurDevice = m_DeviceList[m_iCurSend];
                        }
                        else
                        {
                            if (!m_CurDevice.isWorking)
                            {
                                return;
                            }
                        }
                        continue;
                    }
                }
                watch.Restart();
                Thread.Sleep(PollingTime - ComChlPara.iTimeOut);
                byte[] recBytes = ReadBlock();  // 读取报文
                watch.Stop();
                if (recBytes != null)
                {
                   
                    if (msg.msgType == eMsgType.msgInsSend)
                    {
                        m_DeviceList[msg.devId].NotRecieveCnt = 0; // 连续无接收次数
                        tempDev = m_DeviceList[InsertList[0].DevId];
                        bCheckRes = m_CurDevice.m_Protocol.DealReceiveData(recBytes, ref  tempDev, InsertList[0]);
                    }
                    else
                    {
                        m_CurDevice.NotRecieveCnt = 0; // 连续无接收次数
                        bCheckRes = m_CurDevice.m_Protocol.DealReceiveData(recBytes,ref  m_CurDevice, null);
                    }
                    if (bCheckRes)
                    {
                        ////////////报文显示///////////////////
                        if (msg.msgType == eMsgType.msgSend)
                        {
                            m_CurDevice.m_FreshTime = DateTime.Now;
                            msg.msgType = eMsgType.msgReceiveOK;
                            msg.devId = m_CurDevice.DeviceId;
                            DevIndex = 0;
                            do
                            {
                                m_iCurSend++;                             // 可以考虑只发送锁定的装置数据
                                if (m_iCurSend >= m_DeviceList.Count)
                                {
                                    m_iCurSend = 0;
                                }
                            } while (!m_DeviceList[m_iCurSend].isWorking && (++DevIndex) < m_DeviceList.Count);
                            if (DevIndex < m_DeviceList.Count || m_DeviceList[m_iCurSend].isWorking)
                            {
                                m_CurDevice = m_DeviceList[m_iCurSend];
                            }
                            else
                            {
                                if (!m_CurDevice.isWorking)
                                {
                                    return;
                                }
                            }
                        }
                        else
                        {
                            msg.devId = m_DeviceList[InsertList[0].DevId].DeviceId;
                            msg.msgType = eMsgType.msgInsReceiveOK;
                            if (InsertList.Count > 0)
                            {
                                InsertList.RemoveAt(0); // 移除发送接收正常的插帧
                            }
                        }
                        
                        msg.elapse = watch.ElapsedMilliseconds;
                        msg.msgBytes = recBytes;
                        if (AppMain.MainForm.FrmShowMsg.IChlId == ComChlPara.ChannelId || AppMain.MainForm.FrmShowMsg.IChlId == msg.devId)
                        {
                            AppMain.msgQueue.Enqueue(msg);
                        }
                        //////////////////////////////////////////////
                    }
                    else
                    {
                        ///报文显示///
                        if (msg.msgType == eMsgType.msgSend)
                        {
                            msg.msgType = eMsgType.msgReceiveFail;
                            msg.devId = m_CurDevice.DeviceId;
                        }
                        else
                        {
                            msg.msgType = eMsgType.msgInsReceiveFail;
                            msg.devId = m_DeviceList[InsertList[0].DevId].DeviceId;
                        }
                        msg.elapse = watch.ElapsedMilliseconds;
                        msg.msgBytes = recBytes;
                        if (AppMain.MainForm.FrmShowMsg.IChlId == ComChlPara.ChannelId || AppMain.MainForm.FrmShowMsg.IChlId == msg.devId)
                        {
                            AppMain.msgQueue.Enqueue(msg);
                        }

                        ReSendCnt++;
                        if (ReSendCnt >= m_CurDevice.MaxSendCnt)
                        {
                            ReSendCnt = 1; //初始值为1
                            if (InsertList.Count > 0 && msg.msgType== eMsgType.msgInsReceiveFail)
                            {
                                InsertList.RemoveAt(0); // 移除发送接收正常的插帧
                            }
                            else
                            {
                                do
                                {
                                    m_iCurSend++;                             // 可以考虑锁定发送一台装置的数据
                                    if (m_iCurSend >= m_DeviceList.Count)
                                    {
                                        m_iCurSend = 0;
                                    }
                                } while (!m_DeviceList[m_iCurSend].isWorking && (++DevIndex) < m_DeviceList.Count);
                                if (DevIndex < m_DeviceList.Count || m_DeviceList[m_iCurSend].isWorking)
                                {
                                    m_CurDevice = m_DeviceList[m_iCurSend];
                                }
                                else
                                {
                                    if (!m_CurDevice.isWorking)
                                    {
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
                else  // 无接收报文
                {
                    ///报文显示///
                    if (msg.msgType == eMsgType.msgSend)
                    {
                        msg.msgType = eMsgType.msgReceiveFail;
                        msg.devId = m_CurDevice.DeviceId;
                        if (m_CurDevice.NotRecieveCnt <= m_CurDevice.BreakOffCnt + 1)
                        {
                            m_CurDevice.NotRecieveCnt++;
                        }
                    }
                    else
                    {
                        msg.msgType = eMsgType.msgInsReceiveFail;
                        msg.devId = m_DeviceList[InsertList[0].DevId].DeviceId;
                        if (m_DeviceList[InsertList[0].DevId].NotRecieveCnt <= m_DeviceList[InsertList[0].DevId].BreakOffCnt + 1)
                        {
                            m_DeviceList[InsertList[0].DevId].NotRecieveCnt++;
                        }
                    }
                    msg.elapse = watch.ElapsedMilliseconds;
                    msg.msgBytes = null;
                    if (AppMain.MainForm.FrmShowMsg.IChlId == ComChlPara.ChannelId || AppMain.MainForm.FrmShowMsg.IChlId == msg.devId)
                    {
                        AppMain.msgQueue.Enqueue(msg);
                    }

                    ////////////////////////////////////////////
                    ReSendCnt++;
                    if (ReSendCnt >= m_CurDevice.MaxSendCnt)
                    {
                        ReSendCnt = 1; //初始值为1
                        if (InsertList.Count > 0 && msg.msgType == eMsgType.msgInsReceiveFail)
                        {
                            InsertList.RemoveAt(0); // 移除发送接收正常的插帧
                        }
                        else
                        {
                            do
                            {
                                m_iCurSend++;                             // 可以考虑锁定发送一台装置的数据
                                if (m_iCurSend >= m_DeviceList.Count)
                                {
                                    m_iCurSend = 0;
                                }
                            } while (!m_DeviceList[m_iCurSend].isWorking && (++DevIndex) < m_DeviceList.Count);
  
                            if (DevIndex < m_DeviceList.Count || m_DeviceList[m_iCurSend].isWorking)
                            {
                                m_CurDevice = m_DeviceList[m_iCurSend];
                            }
                            else
                            {
                                if (!m_CurDevice.isWorking)
                                {
                                    return;
                                }
                            }
                        }
                    }
                }
            }
        }
        private void RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e)
        {
            m_iCurSend = 0;
            ReSendCnt = 1;
            for (int i = 0; i < m_DeviceList.Count;i++ )
            {
                m_DeviceList[i].NotRecieveCnt = m_DeviceList[i].BreakOffCnt + 1;
                //m_DeviceList[i].isWorking = false;
                //m_DeviceList[i].m_iNoReceive = 0;
                for (int j =0;j < m_DeviceList[i].GetDataItemCnt(); j++)
                {
                    m_DeviceList[i].GetDataItem(j).nRecCnt = 0;
                    m_DeviceList[i].GetDataItem(j).dCurValue = 0;
                    m_DeviceList[i].GetDataItem(j).nRecCnt = 0; // 内部算法需要
                    m_DeviceList[i].GetDataItem(j).dMinValue =null;
                    m_DeviceList[i].GetDataItem(j).dMaxValue = null;
                }  
            }
            if (ComChlPara.ComPort.IsOpen)
            {
                ComChlPara.ComPort.Close();
            }
        }
        /// <summary>
        /// 发送数据至传送缓冲区
        /// </summary>
        /// <param name="bData"></param>
        /// <returns></returns>
        protected  bool SendBlock(byte[] bData)
        {
            if (bData == null || bData.Length == 0)
            {
                return false;
            }
            _ChlPara.ComPort.DiscardInBuffer();
            _ChlPara.ComPort.DiscardOutBuffer();
            try
            {
                _ChlPara.ComPort.Write(bData, 0, bData.Length);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
            return true;
        }
        /// <summary>
        /// 取出接收缓冲区数据
        /// </summary>
        /// <returns></returns>
        protected  byte[] ReadBlock()
        {
            List<byte> RecBytelist = new List<byte>();
            int iRec = 0;
            if (_ChlPara.ComPort.ReadTimeout < 0)
            {
                _ChlPara.ComPort.ReadTimeout = 25;
                _ChlPara.iTimeOut = 25;
            }
            
            try
            {
                while (iRec != -1) // 测试发现没有出现-1  而是最后读取超时
                {
                    iRec = _ChlPara.ComPort.ReadByte(); // 超时会引发异常（接收第一个字节后超时,作为结束判断）
                    RecBytelist.Add((byte)iRec);
                }
            }
            catch  // 等待超时
            {
                //Console.WriteLine(ex.Message);
                if (RecBytelist.Count > 0)
                {
                    return RecBytelist.ToArray();
                }
                else
                {
                    return null;
                }
            }
            if (RecBytelist.Count > 0)
            {
                return RecBytelist.ToArray();
            }
            else
            {
                return null;
            }
        }
        public override string ToString()
        {
            return "ModbusRTU_InnerChannel";
        }
    }
}
